﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class OneProgress : MonoBehaviour {
	public enum setMonoType{
		ENABLE,DISABLE,DESTROY,ADD,WAITFINISH,INVOKE
	};
	[System.Serializable]
	public class SetMonoBehaviour
	{
		public string targetObjName;
		public string monoName;
		public setMonoType type;
		/// 当INVOKE时是要调用的函数
		public string invokeFunc;
	};
	[System.Serializable]
	public class OneChoice
	{
		public string choiceName;
		public string nextProgress;
	};
	[System.Serializable]
	public class SetGameObject
	{
		public string objName;
		public bool setBool;
	};
	[System.Serializable]
	public class InstGameObject
	{
		public string objName;
		//当为空时表示销毁gameObj
		public string instPos;
	};

	public bool hideNull;

	public string thisProgress;		//任务开始的任务节点
	public string nextProgress;		//任务完成后进入的任务节点
	public float delayTime = 0f;

	///初始工作是否只做一次？
	public bool DoOnce = true;
	bool isDone = false;
	///当有选择分支时开启的分支
	public List<OneProgress> eventChoices;
	///开启任务时要生成/或销毁的物体（没有Transform就是销毁）
	public List<InstGameObject> instObj;
	///开启任务时要激活/禁用的物体
	public List<SetGameObject> enableObj;
	///开启/禁用脚本
	public List<SetMonoBehaviour> SMB;
	List<MonoBehaviour> MBneedWait;
	///完成任务时要从背包中去掉的东西
	public List<string> itemUsed;

	public string RangeName;		//范围物体的名字（玩家进入范围就算完成任务）
	public InputType inputInRange;	//进入范围时要按下的按键类型（输入类型）
	public int InputCount = 1;	//按键要按多少次
	int iCount;

	public List<string> ObjNeedGotten;		//需要获得的物体的名字
	public List<string> ObjNeedLost;		//需要使用或丢弃的物体的名字

	//public string textName;				//要开启的对话
	public TextAsset textAsset;
	ReadTextExample readText;	//对话控制脚本
	///对话选择
	public List<OneChoice> talkChoices;

	/// 任务说明
	public string introduction{ get { return intro; } set { intro = value; } }
	[HideInInspector][SerializeField]
	string intro = "Introduction";

	bool isFinish = false;	//任务完成标记
	float checkPeriod = 0.5f;	//检查任务是否完成的周期

	Coroutine waitCoroutine;


	///不能用Start函数，因为Start函数只会执行一次，以后无法重新激活
	public void StartTask(){
		Invoke ("startLater", delayTime);
	}
	void startLater(){
		print ("Task" + thisProgress + " start!");
		iCount = InputCount;
		if (!(DoOnce && isDone)) {
			taskInitial ();
		}
		if (eventChoices.Count>0) {
			int len = eventChoices.Count;
			for (int i = 0; i < len; i++) {
				//eventChoices [i].readText = readText;
				eventChoices [i].enabled = true;
				eventChoices [i].StartTask ();
			}
			this.enabled = false;
		} else {
			waitCoroutine = StartCoroutine (waitFinished ());
		}
	}
	/// <summary>
	/// 任务开始的操作
	/// 主要是生成或激活物体
	/// 并且要保证有分支时也只执行一次
	/// </summary>
	void taskInitial(){
		//print ("pro="+thisProgress.ToString());
		//print ("time="+Time.time.ToString());
		isParOK ();
		foreach (InstGameObject ig in instObj) {
			if (ig.instPos != "") {
				ItemFlag flagOnInstPos = ItemManager.GetItemFlag (ig.instPos);
				GameObject prefab = ItemManager.ItemMan.getPrefabInAllObj (ig.objName);
				if (prefab==null) {
					Debug.LogError ("The object named " + ig.objName + " isn't existed");
				}
				ItemManager.InstantiateItem (prefab, flagOnInstPos.transform.position, flagOnInstPos.transform.rotation);
			} else {
				ItemManager.DestroyItem (ig.objName);
			}
		}
		foreach (SetGameObject sg in enableObj) {
			ItemManager.EnableItem (sg.objName, sg.setBool);
		}
		foreach (SetMonoBehaviour smb in SMB) {
			switch (smb.type) {
			case setMonoType.ENABLE:
				(ItemManager.GetItemFlag (smb.targetObjName).GetComponent (smb.monoName) as MonoBehaviour).enabled = true;
				break;
			case setMonoType.DISABLE:
				(ItemManager.GetItemFlag (smb.targetObjName).GetComponent (smb.monoName) as MonoBehaviour).enabled = false;
				break;
			case setMonoType.DESTROY:
				Destroy (ItemManager.GetItemFlag (smb.targetObjName).GetComponent (smb.monoName));
				break;
			//case setMonoType.ADD:
			//	ItemManager.GetItemFlag (smb.targetObjName).gameObject.AddComponent (smb.monoName.GetType ());
			//	break;
			///特殊事件，需要等待脚本完成任务
			case setMonoType.WAITFINISH:
				if (MBneedWait == null) {
					MBneedWait = new List<MonoBehaviour> ();
				}
				MonoBehaviour m = (ItemManager.GetItemFlag (smb.targetObjName).GetComponent (smb.monoName) as MonoBehaviour);
				m.enabled = true;
				MBneedWait.Add (m);
				break;
			case setMonoType.INVOKE:
				(ItemManager.GetItemFlag (smb.targetObjName).GetComponent (smb.monoName) as MonoBehaviour).Invoke (smb.invokeFunc, 0f);
				break;
			default:
				break;
			}
		}
		foreach (string itName in ObjNeedGotten) {
			TaskItem.addTaskItemTo (ItemManager.GetItemFlag (itName).gameObject, TaskItemsNeedAdded.GetTaskItem (itName));
		}

		if(textAsset!=null){
			//开启对话
			readText = ReadTextExample.CreateTalkCanvas (textAsset, 
				StaticVarFunc.Player.transform.position + StaticVarFunc.Player.transform.up * 1f + StaticVarFunc.Player.transform.forward * 1f, 
				StaticVarFunc.Player.transform.rotation).GetComponent<ReadTextExample> ();
		}
	}
	/// <summary>
	/// 检查任务的参数是否正确不缺损
	/// </summary>
	/// <returns><c>true</c>, if par O was ised, <c>false</c> otherwise.</returns>
	bool isParOK(){
		return true;
	}

	/// <summary>
	/// 等待任务完成
	/// </summary>
	/// <returns>The finished.</returns>
	IEnumerator waitFinished(){
		if (RangeName != "") {
			PlayerInRange pir = ItemManager.GetItemFlag (RangeName).GetComponent<PlayerInRange> ();
			while (!isFinish) {
				yield return null;
				if (pir.isPlayerInRange () && MyInput.GetInputOfType (inputInRange)) {
					if (--iCount<=0) {
						isFinish = true;
					}
				}
			}
		}
		//注意此处的List由于被序列化，已经不是null了
		else if (ObjNeedGotten.Count > 0) {
			while (!isFinish) {
				yield return new WaitForSeconds (checkPeriod);
				int len = ObjNeedGotten.Count;
				isFinish = true;
				for (int i = 0; i < len; i++) {
					if (!StaticVarFunc.backpack.isContains (ObjNeedGotten [i])) {
						isFinish = false;
					}
				}
			}
		}
		//注意此处的List由于被序列化，已经不是null了
		else if (ObjNeedLost.Count > 0) {
			while (!isFinish) {
				yield return new WaitForSeconds (checkPeriod);
				int len = ObjNeedLost.Count;
				for (int i = 0; i < len; i++) {
					if (!StaticVarFunc.backpack.isContains (ObjNeedLost [i])) {
						isFinish = true;
					}
				}
			}
		}
		//对话的选择可能有几个，最终结果完全由最后一个选择决定
		//必须保证每个选择的名字不一样
		else if (readText != null) {
			while (!isFinish) {
				yield return new WaitForSeconds (checkPeriod);
				if (readText.IsOver) {
					isFinish = true;
					//print (readText.theChoices [0]);
					if (readText.theChoices.Count > 0) {
						foreach (string ch in readText.theChoices) {
							foreach (OneChoice oc in talkChoices) {
								if (ch == oc.choiceName) {
									nextProgress = oc.nextProgress;
								}
							}
						}
					}
				}
			}
		} 
		///等待脚本完成任务
		else if (MBneedWait!=null) {
			System.Type t;
			System.Reflection.FieldInfo fi;
			while (!isFinish) {
				bool allFinish = true;
				foreach (MonoBehaviour mb in MBneedWait) {
					t = mb.GetType ();
					fi = t.GetField ("isFinishProgress");
					allFinish = ((bool)fi.GetValue (mb)) ? allFinish : false;
				}
				isFinish = allFinish;
				yield return new WaitForSeconds (checkPeriod);
			}
		}
		if (!isFinish && itemUsed.Count <= 0) {
			print ("Task has no content");
		}
		taskEnd ();
		yield return null;
	}

	/// <summary>
	/// 任务完成时执行的代码
	/// </summary>
	void taskEnd(){
		foreach (string itemName in itemUsed) {
			StaticVarFunc.backpack.useItem (itemName);
		}
		isFinish = false;
		GetComponentInParent<GameProgressManager> ().GameProgress = nextProgress;
		print ("Task" + thisProgress + " Finish!");
	}

	/// <summary>
	/// 异常处理（比如任务未完成时任务被强制退出）
	/// </summary>
	void ExceptionHandling(){
		
	}

	public void stopProgress(){
		//StopCoroutine ("waitFinished");
		//StopCoroutine (waitFinished ());
		//StopAllCoroutines();	//其他方法居然停不了协程？？？？
		if(waitCoroutine!=null){
			StopCoroutine(waitCoroutine);
			waitCoroutine = null;
		}
	}

	public void finishTask(){
		isFinish = true;
	}
}
